import React, { useContext } from 'react';
import { FieldProps } from '@rjsf/utils';
import {
  Checkbox,
  Flex,
  Input,
  InputNumber,
  InputNumberProps,
  InputProps,
  message,
} from 'antd';
import { MessageContext } from '../CollapseTemplate';

/**
 * @description 自定义组件
 * @param {FieldProps} props
 * @returns {JSX.Element}
 * @example 
 * schema: {
      InputField: {
      type: 'string'/'number'/'object',
      title: '输入框',
      default: '123'/123/{
        value: '123'/123,
        checked: false
      },
    }
 * uiSchema: {
    'ui:FieldTemplate': InputField,
    'ui:prefix': 'expand level=',
    'ui:suffix': 'm'
  }
 */
export const InputField = ({
  schema,
  formData,
  uiSchema,
  onChange,
  disabled,
}: FieldProps<string | number | object | null>): JSX.Element => {
  const { layout: layout1 } = useContext(MessageContext);
  // 布局，label和输入框的占比
  const layout = uiSchema?.['ui:layout'] ?? layout1 ?? [1, 1];
  const options = uiSchema?.['ui:options'] ?? {};

  // 检查value和需要显示checkbox
  // TODO 这里好像有点复杂，是不是应该拆成两个组件呢？
  let value = formData ?? schema.default;
  let inputType: string = schema.type as string;
  const initData = formData ?? schema.default;
  let checked: boolean = undefined;
  let hasCheckBox = false;
  if (inputType === 'object' && initData instanceof Object) {
    value = initData['value'];
    inputType = typeof value;
    hasCheckBox = true;
    checked = initData['checked'];
  }

  let minValue: number = undefined;
  let maxValue: number = undefined;
  minValue = schema.exclusiveMinimum;
  // 实际最小值：如果是 exclusiveMinimum ，则加一点偏移
  minValue = minValue !== undefined ? minValue + 1e-10 : schema.minimum;

  maxValue = schema.exclusiveMaximum;
  // 实际最大值：如果是 exclusiveMaximum ，则减一点偏移
  maxValue = maxValue !== undefined ? maxValue - 1e-10 : schema.maximum;

  const disabledBoolean = disabled
    ? disabled
    : (uiSchema?.['ui:disabled'] ?? false);
  const pattern: any = options?.pattern;

  const props = {
    status: pattern ? (pattern?.test(formData) ? '' : 'error') : '',
    disabled: disabledBoolean || checked === false,
    type: inputType,
    prefix: uiSchema?.['ui:prefix'],
    suffix: uiSchema?.['ui:suffix'],
    value: value,
  };
  const schemaDefaulr: any = schema?.default;
  const numberType = schemaDefaulr?.number;
  const handleChange = (value: string | number) => {
    if (schema.english && value) {
      const strValue = value.toString();
      if (!/^[\w\s\-@#%,:;'"*+=[\]{}()/\\]*$/.test(strValue)) {
        message.warning('仅允许字母、数字和_-@#%等符号');
        return onChange('');
      }
    }
    onChange(hasCheckBox ? { value, checked } : value);
  };
  return (
    <Flex
      style={{ gap: 4 }}
      className='items-center'>
      <div
        className='fs'
        style={{ flex: layout[0] }}>
        {hasCheckBox ? (
          <Checkbox
            disabled={disabledBoolean}
            defaultChecked={checked}
            onChange={(e) => onChange({ checked: e.target.checked, value })}>
            {schema.title}
          </Checkbox>
        ) : (
          schema.title
        )}
      </div>
      <div style={{ flex: layout[1] }}>
        {inputType === 'number' ||
        inputType === 'integer' ||
        schemaDefaulr?.number ? (
          <InputNumber
            min={minValue}
            max={maxValue}
            placeholder='请输入'
            precision={inputType === 'integer' ? 0 : undefined}
            style={{ width: '100%', height: 'var(--input-height)' }}
            {...(props as InputNumberProps<number>)}
            onChange={(value) => handleChange(value)}
          />
        ) : (
          <Input
            {...(props as InputProps)}
            placeholder='请输入'
            onChange={(e) => handleChange(e.target.value)}
          />
        )}
      </div>
    </Flex>
  );
};
